﻿// dxbc-spirv.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include "../dxbc-spirv-static/dxbc/dxbc_module.h"

using namespace dxvk;

bool ReadBin(const char* szFile, uint8_t** ppBuf, uint32_t& nLen)
{
    FILE* fp = fopen(szFile, "rb");
    if (!fp)
    {
        return false;
    }

    fseek(fp, 0, SEEK_END);
    nLen = ftell(fp);
    rewind(fp);
    uint8_t* pBuf = new uint8_t[nLen]();
    if (!pBuf)
    {
        return false;
    }
    fread(pBuf, nLen, 1, fp);
    fclose(fp);

    *ppBuf = pBuf;

    return true;
}

bool WriteBin(const char* szFile, uint8_t* pData, uint32_t nLen)
{
    FILE* fp = fopen(szFile, "wb");
    if (!fp)
    {
        return false;
    }
    fwrite(pData, nLen, 1, fp);
    fclose(fp);

    return true;
}

int main(int argc, char* argv[])
{
    uint32_t BytecodeLength = 0;
    uint8_t* pShaderBytecode = NULL;
    if (!ReadBin(argv[1], &pShaderBytecode, BytecodeLength))
    {
        std::cout << "read dxbc fail!\n";
        return 1;
    }

    DxbcReader reader(
        reinterpret_cast<const char*>(pShaderBytecode),
        BytecodeLength);

    DxbcFloatControlFlags f(15);
    DxbcModuleInfo DxbcModuleInfo = {};
    DxbcModuleInfo.options.minSsboAlignment = 4;
    DxbcModuleInfo.options.supportsTypedUavLoadR32 = true;
    DxbcModuleInfo.options.invariantPosition = true;
    DxbcModuleInfo.options.floatControl.set(f);

    std::string name = argv[1];
    name.append(".spv");
    DxbcModule module(reader);
    SpirvCodeBuffer buf = module.compile(DxbcModuleInfo, name);
    if (!WriteBin(name.c_str(), (uint8_t*)buf.data(), buf.dwords() * 4))
    {
        std::cout << "Write spirv fail!\n";
        return 1;
    }
    std::cout << "dxbc to spirv ok!\n";
    return 0;
}
